/**
 * Copyright 2009 Jesse Brown (jbrown@fluentv.com)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package com.fluentv.games.netblocks;

import android.graphics.Color;

import com.fluentv.games.netblocks.piece.*;

/**
 * Shape factory to spit out various standard kinds of shapes.
 * 
 * TODO: Weird mix here of static setup in this class with concrete
 * types for each shape. Probably better to do it all here and use
 * a single class, or do it all in the individual classes?
 * 
 * @author Jesse Brown (jbrown@fluentv.com)
 */
public class ShapeFactory {
  private static ShapeFactory instance = new ShapeFactory();

  private int lastRandomShapeId;
  
  /**
   * Singleton instance.
   */
  private ShapeFactory() {    
  }
  
  /**
   * Retrieve the singleton instance
   */
  public static ShapeFactory getInstance() {
    return instance;
  }
     
  /**
   * Return a 2x2 block red square
   * @return new Shape object
   */
  public Shape buildSquare() {
    return new SquareShape(2, Color.RED);
  }
 
  /**
   * Return a line shape. 
   */
  public Shape buildLine() {
    return new LineShape(4, Color.CYAN);
  }
  
  /**
   * Return a L shape.
   */
  public Shape buildL() {
    return new LShape(3, 2, Color.BLUE);
  }
  
  /**
   * Return a Z shape, 2 blocks on top and bottom.
   */
  public Shape buildZ() {
    return new ZShape(2, Color.GREEN);
  }
  
  /**
   * Return an inverted Z shape, 2 blocks on bottom and top
   */
  public Shape buildInvertedZ() {
    return new InvertedZShape(2, Color.RED);
  }
  
  /**
   * Return an inverted L shape
   */
  public Shape buildInvertedL() {
    return new InvertedLShape(3, 2, Color.GRAY);
  }
  
  /**
   * Return a hollow delta shape   
   */
  public Shape buildHollowDelta() {
    return new HollowDeltaShape(Color.MAGENTA);
  }
  
  /**
   * Return a T shape
   */
  public Shape buildT() {
    return new TShape(Color.WHITE);
  }
  
  /**
   * Return a Cross shape
   */
  public Shape buildCross() {
    return new CrossShape(Color.YELLOW);
  }
  
  /**
   * Return a random shape with a random color.
   * @return new random shape.
   */
  public synchronized Shape buildRandomShape() {
    int choices = 7;
    
    int shapeId;
    do {
      shapeId = (int) (Math.random() * choices) + 1; 
    } while (shapeId == lastRandomShapeId);
    
    lastRandomShapeId = shapeId;
    
    switch (shapeId) {
      case 1:
        return buildLine();
      case 2:
        return buildL();
      case 3:
        return buildInvertedL();
      case 4:
        return buildZ();
      case 5:
        return buildInvertedZ();
      case 6:
        return buildT();
      default:
        return buildSquare();    
    }
  } 
}
